-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Combine Query and QueryLens using a type parameter for state, but don't introduce owned iterators
#19787
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
ElliottjPierce
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm broadly on board with this. I do something similar for my ecs too.
It's really hard to see the changes to all the*_inner functions that return 'w types, but I'm assuming those were just copied over. And the asm didn't change, so the impl is still correct.
The only thought I have is to change S: Deref<Target = QueryState<D, F>> to S: Borrow<QueryState<D, F>>. That would let this work with an owned state directly. In fact, you might even be able to get rid of the Box in the query lens.
Yeah, I did put the moves in their own commit in case that helps, but it's still hard to confirm that that commit really is just a move. I wish we had better tooling for reviewing things like that!
Hah, yeah, that's what I did first :). @Victoronz convinced me that |
That makes a lot of since. I still hate to loose all the flexibility that |
Victoronz
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While there is some follow-up to be done, I think this is a good next step!
Hope realigning the changes with main isn't too tedious.
…tate-simple # Conflicts: # crates/bevy_ecs/src/system/query.rs
|
Marked as X-Controversial as it adds another generic to |
|
To clarify some of the benefits this direction has: This led to various cases where we could not directly create a usable Further, this direction allows us to more closely match the I believe that such improvements surrounding Additionally, this should ease the design space for Queries-as-Entities ( Overall, I think the simplifications it will allow are worth the surface complexity it introduces! The |
|
As Victoronz stated above, some other features like Uncached Queries or MultiSource Queries (Relation Queries) will also need that third generic on Query, so I think it's a step in the right direction! Currently the third generic is It's easier to introduce this third generic for the owned/borrowed case because the code changes are small and the use-case is pretty clear. |
Yup, that label seems appropriate!
I'll note that defaulted generic parameters are usually pretty invisible to users. I often forget that
One of my goals here is to make So, it's not so much about the current uses of
I don't think I see how this change would help with that. The It might be possible to remove the |
alice-i-cecile
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With a bit more docs this LGTM. These arguments have convinced me!
How I see it, this change gives us a new lever manipulate But for now, this is still a suspicion! It might also be that the situations I've seen were hindered by the tech debt that can be addressed as follow-ups to this PR if it goes through, or that there'd be other issues to run into. |
…tate-simple # Conflicts: # crates/bevy_ecs/src/system/query.rs
…tate-simple # Conflicts: # crates/bevy_ecs/src/system/query.rs
| /// A [`Query`] with an owned [`QueryState`]. | ||
| /// | ||
| /// This is returned from methods like [`Query::transmute_lens`] that construct a fresh [`QueryState`]. | ||
| pub type QueryLens<'w, Q, F = ()> = Query<'w, 'static, Q, F, Box<QueryState<Q, F>>>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this going to mess up people who want to take a query as a parameter into a function? i.e. are they going to have to be generic over the cache type now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this going to mess up people who want to take a query as a parameter into a function? i.e. are they going to have to be generic over the cache type now?
No, the new type parameter has a default, so it should all be backwards compatible. Functions will only need to be generic over the cache type if they want to work with both Query and QueryLens.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's what I was trying to say. At the very least this needs to be mentioned in the migration guide as that's one of the main uses of QueryLens.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I thought the intended usage was the one in the transmute_lens docs, where the reusable function takes a QueryLens. That case will work unchanged. (Edit: And by "unchanged" I mean other than removing the call to .query().)
If a user instead has a function that takes a Query and are calling it like foo(query_lens.query()), then they'll get a warning that query() is deprecated. The deprecation message and the migration guide both mention that the reborrow() method can be used instead.
I suppose we could note that they could also make the function generic, but reborrow() is going to be the cleaner solution in most cases, and it covers any existing code, so I'd rather stick with recommending that.
Objective
Make
QueryLenseasier to use by allowing query methods to be called on it directly instead of needing to call thequery()method first.Split out from #18162. I thought this might be easier to review separately, but if we do merge #18162 then this PR will no longer be necessary.
Solution
Make
Queryand the various iterator types generic, where normal queries use borrowed&QueryState<D, F>andQueryLensuses ownedBox<QueryState<D, F>>.Have
Queryuse a default type for the state so that it continues to work without specifying it explicitly.Note that the
'statelifetime onQuerywas only used in&'state QueryState, so it is now only used in the default type parameter. It still needs to be part of theQuerytype in order to be referenced in the default type, so we need aPhantomDataso that it's actually used.Testing
I used
cargo-show-asmto verify that the assembly ofQuery::iterdid not change.This rust code:
Run with
Results in the same asm before and after the change